﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
using SharpCmd.IO;
using SharpCmd.Windows.Forms;

namespace SharpCmd.Controls.FileSystemViewers
{
    internal partial class FullFSViewer : FileSystemViewer, IFileSystemViewer
    {
        #region ctor
        public FullFSViewer()
        {
            InitializeComponent();
            this.ViewControl = listViewFS;
            this.PathChanged += new Util.PathChangedDelegate(FullFSViewer_PathChanged);
            listViewFS.ItemActivate += new EventHandler(ListViewFS_ItemActivate);
            listViewFS.GoToParentDirectory += new EventHandler(ListViewFS_GoToParentDirectory);
            listViewFS.SelectedIndexChanged += new EventHandler(ListViewFS_SelectedIndexChanged);
        }
        #endregion

        #region events
        public override event Util.PathChangedDelegate PathChanged;
        public override event SelectedIndexChangedHandler SelectedIndexChanged;
        public override event Util.DriveChangedDelegate DriveChanged;
        #endregion

        #region properties
        public override string Text
        {
            get
            {
                return (new DirectoryInfo(Path)).FullName;
            }
        }

        public override string Path
        {
            get
            {
                return path;
            }
            set
            {
                path = value;
                if (PathChanged != null)
                    PathChanged(this, path);
            }
        }

        /// <summary>
        /// Gets first selected item OR a focused item
        /// </summary>
        public override FSObjectInfo SelectedItem
        {
            get
            {
                ListViewItemEx item = listViewFS.OneSelectedItem as ListViewItemEx;
                return item == null ? null : item.Info;
            }
        }

        public override FSObjectInfo FocusedItem
        {
            get
            {
                ListViewItemEx item = listViewFS.FocusedItem as ListViewItemEx;
                return item == null ? null : item.Info;
            }
        }

        public override bool HasSelectedItem
        {
            get
            {
                if (listViewFS.SelectedItems.Count == 0 && listViewFS.FocusedItem == null)
                    return false;
                else
                    return true;
            }
        }

        public override List<FSObjectInfo> SelectedItemInfos
        {
            get { return listViewFS.SelectedItemInfos; }
        }
        #endregion

        /// <summary>
        /// Displays current directory
        /// </summary>
        public override void Reload()
        {
            listViewFS.BeginUpdate();
            listViewFS.Items.Clear();
            foreach (var item in GetFSInfos())
            {
                ListViewItemEx lvi = new ListViewItemEx(item.GetFullInfos());
                lvi.UseItemStyleForSubItems = false;
                lvi.Info = item;
                listViewFS.Items.Add(lvi);
            }
            listViewFS.EndUpdate();
            listViewFS.FocusItem();
        }

        public override void DoFocus()
        {
            ViewControl.Focus();
        }

        public override void GoToParentDirectory()
        {
            string oldPath = Path;
            base.GoToParentDirectory();
            //pre-select an item in ListViewFS
            FocusItemWithPath(oldPath);
        }

        public override void FocusItemWithPath(string path)
        {
            listViewFS.FocusItemWithPath(path);
        }

        public override void Sort(SortType sortType)
        {
            listViewFS.Sort(sortType);
        }

        public override void InvertSelection()
        {
            listViewFS.InvertSelection();
        }

        public override void SelectAll()
        {
            listViewFS.SelectAll();
        }

        public override void SelectSameExtension()
        {
            listViewFS.SelectSameExtension();
        }

        public override void Select(string group)
        {
            listViewFS.SetSelectedForFilter(group,true);
        }

        public override void UnSelect(string group)
        {
            listViewFS.SetSelectedForFilter(group, false);
        }

        public override void OnDriveChanged(string drive)
        {
            throw new NotImplementedException();
        }

        #region listViewFS event handlers
        private void ListViewFS_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (SelectedIndexChanged != null)
                SelectedIndexChanged(listViewFS.FileCount, listViewFS.DirectoryCount, listViewFS.SelectedFileCount, listViewFS.SelectedDirectoryCount, listViewFS.TotalSize, listViewFS.SelectedSize);
        }

        private void ListViewFS_ItemActivate(object sender, EventArgs e)
        {
            //TODO move to base class
            //execute file or enter directory
            var item = listViewFS.FocusedItem as ListViewItemEx;
            if (item.Info.Type == FSObjectType.File)
            {
                //TODO check if item still exists
                System.Diagnostics.Process p = new System.Diagnostics.Process();
                System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo(item.Info.FullName);
                p.StartInfo = psi;
                p.Start();
            }
            else if (item.Info.Type == FSObjectType.Directory)
            {
                if (!Directory.Exists(item.Info.FullName))
                    MessageBox.Show("Path " + item.Info.FullName + " does not exist!");
                if (item.Info.Fake && item.Info.Name == "..")
                {
                    GoToParentDirectory();
                    return;
                }
                Path = item.Info.FullName;
            }
        }

        private void ListViewFS_GoToParentDirectory(object sender, EventArgs e)
        {
            GoToParentDirectory();
        }
        #endregion

        /// <summary>
        /// Handles path changed event - changes path, updates header
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="path"></param>
        private void FullFSViewer_PathChanged(object sender, string path)
        {
            fsViewerHeader.SetPath(path);
            Reload();
            if (SelectedIndexChanged != null)
                SelectedIndexChanged(listViewFS.FileCount, listViewFS.DirectoryCount, listViewFS.SelectedFileCount, listViewFS.SelectedDirectoryCount, listViewFS.TotalSize, listViewFS.SelectedSize);
        }

        #region resize
        private void ListViewFS_Resize(object sender, EventArgs e)
        {
            const int MIN_DATE_SIZE = 146;
            const int MIN_SIZE_SIZE = 90;
            const int MIN_EXT_SIZE = 45;
            const int MIN_ATTR_SIZE = 40;
            chExtension.Width = MIN_EXT_SIZE;
            chSize.Width = MIN_SIZE_SIZE;
            chDate.Width = MIN_DATE_SIZE;
            chAttributes.Width = MIN_ATTR_SIZE;
            chName.Width = listViewFS.ClientSize.Width - chDate.Width - chExtension.Width - chSize.Width - chAttributes.Width;
        }
        #endregion
    }
}